// Copyright 2011 George Cook
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "BaseTest.h"
#import "Injective.h"
#import "InjectiveContextXMLFactory.h"
#import "InjectiveObjectDescription.h"
#import "InjectivePropertyDescription.h"
#import "InjectivePropertyValueDescription.h"
#import "InjectiveArrayPropertyValueDescription.h"

@interface InjectiveArrayPropertyValueXMLFactoryTest : BaseTest
{
	InjectiveContextXMLFactory *factory;
}
@end


@implementation InjectiveArrayPropertyValueXMLFactoryTest
- (void)setUp
{
	factory = [[InjectiveContextXMLFactory alloc] init];
}

- (void)tearDown
{
	[factory release], factory = nil;
}

- (void)testArrayValue
{
	NSArray *descriptions = [factory processXMLFile:@"testArrayValue.xml"];
	GHAssertNotNil(descriptions, @"no descriptions were generated");
	InjectiveObjectDescription *description = [descriptions lastObject];
	GHAssertNotNil(description.propertyDescriptions, @"there were no property descriptions");
	GHAssertTrue(1 == description.propertyDescriptions.count, @"didn't create 1 property, created %d", description.propertyDescriptions.count);
	InjectivePropertyDescription *propertyDescription = [description.propertyDescriptions lastObject];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Array"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"arrayValue"],@"didn't detect correct property name");
	InjectiveArrayPropertyValueDescription *arrayDescription = (InjectiveArrayPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(arrayDescription,@"value wasn't set");
	GHAssertTrue(arrayDescription.class == [InjectiveArrayPropertyValueDescription class],@"was not an array class");
	GHAssertNil(arrayDescription.propertyValueText,@"text is not set for array descriptions");
	GHAssertTrue([arrayDescription.type isEqualToString:@"Array"],@"didn't set propertyvalue type");
	
	//check values were correctly set
	NSArray *values = arrayDescription.valueDescriptions;
	GHAssertTrue(3 == values.count, @"didn't create 1 property, created %d", values.count);
	
	InjectivePropertyDescription *arrayValuePropertyDescription = [values objectAtIndex:0];
	InjectivePropertyValueDescription *valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"1"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:1];
	valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:2];
	GHAssertNotNil(arrayValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([arrayValuePropertyDescription.type isEqualToString:@"FunkyProvider"],@"didn't set propertyvalue text");
}

- (void)testNestedArrayValue
{
	NSArray *descriptions = [factory processXMLFile:@"testNestedArrayValue.xml"];
	GHAssertNotNil(descriptions, @"no descriptions were generated");
	InjectiveObjectDescription *description = [descriptions lastObject];
	GHAssertNotNil(description.propertyDescriptions, @"there were no property descriptions");
	GHAssertTrue(1 == description.propertyDescriptions.count, @"didn't create 1 property, created %d", description.propertyDescriptions.count);
	InjectivePropertyDescription *propertyDescription = [description.propertyDescriptions lastObject];
	GHAssertTrue([propertyDescription.type isEqualToString:@"Array"],@"didn't detect correct type");
	GHAssertTrue([propertyDescription.propertyName isEqualToString:@"arrayValue"],@"didn't detect correct property name");
	InjectiveArrayPropertyValueDescription *arrayDescription = (InjectiveArrayPropertyValueDescription *)propertyDescription.value;
	GHAssertNotNil(arrayDescription,@"value wasn't set");
	GHAssertTrue(arrayDescription.class == [InjectiveArrayPropertyValueDescription class],@"was not an array class");
	GHAssertNil(arrayDescription.propertyValueText,@"text is not set for array descriptions");
	GHAssertTrue([arrayDescription.type isEqualToString:@"Array"],@"didn't set propertyvalue type");
	
	//check values were correctly set
	NSArray *values = arrayDescription.valueDescriptions;
	GHAssertTrue(4 == values.count, @"didn't create 1 property, created %d", values.count);
	
	InjectivePropertyDescription *arrayValuePropertyDescription = [values objectAtIndex:0];
	InjectivePropertyValueDescription *valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"1"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:1];
	valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:2];
	GHAssertNotNil(arrayValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([arrayValuePropertyDescription.type isEqualToString:@"FunkyProvider"],@"didn't set propertyvalue text");
	
	arrayValuePropertyDescription = [values objectAtIndex:3];
	GHAssertTrue([arrayValuePropertyDescription.type isEqualToString:@"Array"],@"didn't detect correct type");
	arrayDescription = (InjectiveArrayPropertyValueDescription *)arrayValuePropertyDescription.value;
	GHAssertNotNil(arrayDescription,@"value wasn't set");
	GHAssertTrue(arrayDescription.class == [InjectiveArrayPropertyValueDescription class],@"was not an array class");
	GHAssertNil(arrayDescription.propertyValueText,@"text is not set for array descriptions");
	GHAssertTrue([arrayDescription.type isEqualToString:@"Array"],@"didn't set propertyvalue type");
	
	//nested properties
	values = arrayDescription.valueDescriptions;
	GHAssertTrue(3 == values.count, @"didn't create properties, created %d", values.count);
	
	arrayValuePropertyDescription = [values objectAtIndex:0];
	valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"2"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"Integer"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:1];
	valueDescription = arrayValuePropertyDescription.value;
	GHAssertNotNil(valueDescription,@"value wasn't set");
	GHAssertTrue(valueDescription.class == [InjectivePropertyValueDescription class],@"was not a primitve class");
	GHAssertTrue([valueDescription.propertyValueText isEqualToString:@"some text2"],@"didn't set propertyvalue text");
	GHAssertTrue([valueDescription.type isEqualToString:@"String"],@"didn't set propertyvalue type");
	
	arrayValuePropertyDescription = [values objectAtIndex:2];
	GHAssertNotNil(arrayValuePropertyDescription,@"value wasn't set");
	GHAssertTrue([arrayValuePropertyDescription.type isEqualToString:@"FunkyProvider2"],@"didn't set propertyvalue text");
	
}
@end
